Conversation
Feat/api sign up
fix: 이미지 조회 div 높이 수정 및 css 주석 삭제
feat: 일기 추천 조회 및 목록 조회 추가
feat: api 채팅 추가
feat: 사용자 정보 조회, 달력 조회 연동 추가
fix: 헤더 로그인시 문제 해결
- 회원 정보 불러오기 - 회원 탈퇴(미완) - 비밀번호 변경(미완) - 프로필 변경(미완)
- 회원정보 불러오기 - 회원 탈퇴 - 비번 변경 - 프로필 변경
마이페이지 api 연동
fix: 토큰 만료시 로그아웃 되도록 설정
fix: 코드래빗 코드 반영
fix: AI 피드백이 오지 않았을 때 기능 추가
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/pages/EditDiary.jsx (1)
88-94:⚠️ Potential issue | 🟡 Minor감정 카테고리 아이콘에
cursor: pointer가 있지만 클릭 핸들러가 없습니다.
CategoryImg스타일(line 192)에cursor: pointer가 설정되어 있어 클릭 가능해 보이지만, 실제로onClick핸들러가 연결되어 있지 않습니다. 사용자가 감정을 수정할 수 없다면 커서 스타일을 제거하고, 수정 가능하다면 핸들러를 구현해야 합니다.💡 클릭 불가능한 경우 커서 스타일 제거
const CategoryImg = styled.img` width: 40px; height: 40px; - cursor: pointer; `;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/EditDiary.jsx` around lines 88 - 94, Category icons (CategoryImg) show a pointer cursor but lack click handlers; either remove the cursor from the CategoryImg styled-component or make them interactive by adding state and onClick handlers: in EditDiary add a piece of state like selectedEmotion and a handler function handleSelectEmotion(emotion) that calls setSelectedEmotion, pass onClick={() => handleSelectEmotion('happy'|'sad'|...)} to each CategoryImg instance, and update CategoryImg styling to accept a selected prop (e.g., props.selected) to render a visible selected style and keep cursor: pointer only when an onClick/clickable prop is present.
🧹 Nitpick comments (4)
src/pages/Home.jsx (3)
257-269: 사진 목록에서index를key로 사용하고 있습니다.사진이 재정렬되거나 변경될 수 있다면
diaryId또는 고유 식별자를 key로 사용하는 것이 더 안전합니다.💡 고유 key 사용 제안
-{recentPhotos.slice(0, 3).map((photo, index) => ( - <RecentImageWrapper - key={index} +{recentPhotos.slice(0, 3).map((photo) => ( + <RecentImageWrapper + key={photo.diaryId} onClick={() => handlePhotoClick(photo.diaryId)} >🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/Home.jsx` around lines 257 - 269, The list is using the loop index as the React key which can cause incorrect rendering when items reorder; update the mapping in the RecentPhotosList to use a stable unique identifier (e.g., photo.diaryId) as the key instead of index — locate the map over recentPhotos (where RecentImageWrapper, RecentImage and handlePhotoClick are used) and change key from index to the unique id (or a stable fallback property if diaryId may be absent).
170-171: 날짜 형식 파싱에서 예외 처리가 필요할 수 있습니다.
recommendation.targetDate가 예상과 다른 형식(예:YYYY-MM-DD가 아닌 경우)이면split("-")와parseInt에서 의도치 않은 결과가 발생할 수 있습니다.💡 방어적 파싱 제안
+const formatRecommendationDate = (dateStr) => { + const parts = dateStr?.split("-"); + if (!parts || parts.length !== 3) return dateStr || ""; + return `${parts[0]}년 ${parseInt(parts[1], 10)}월 ${parseInt(parts[2], 10)}일`; +}; + const getRecommendationDisplay = () => { // ... - const dateParts = recommendation.targetDate.split("-"); - const formattedDate = `${dateParts[0]}년 ${parseInt(dateParts[1], 10)}월 ${parseInt(dateParts[2], 10)}일`; + const formattedDate = formatRecommendationDate(recommendation.targetDate);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/Home.jsx` around lines 170 - 171, The date parsing for recommendation.targetDate is brittle: validate that recommendation.targetDate is a string matching the expected YYYY-MM-DD pattern before calling split and parseInt, e.g., check typeof recommendation.targetDate === 'string' and a simple regex like /^\d{4}-\d{1,2}-\d{1,2}$/; if validation fails, use a safe fallback (e.g., empty string, null, or a localized "Invalid date" label) for formattedDate and avoid calling dateParts[?] or parseInt, and ensure dateParts length is checked (dateParts.length === 3) before constructing formattedDate to prevent runtime errors in the code that defines dateParts and formattedDate.
56-86: 첫 번째useEffect에서 비동기 작업 취소 처리가 누락되었습니다.두 번째
useEffect(lines 88-109)에서는cancelled플래그를 사용하여 컴포넌트 언마운트 시 상태 업데이트를 방지하고 있지만, 이useEffect에서는 동일한 패턴이 적용되지 않았습니다. 컴포넌트가 언마운트된 후 API 응답이 도착하면 메모리 누수 경고가 발생할 수 있습니다.♻️ 취소 플래그 추가 제안
useEffect(() => { + let cancelled = false; + const fetchData = async () => { try { const diaryRes = await getDiariesList(); + if (cancelled) return; const diaryData = Array.isArray(diaryRes) ? diaryRes : (diaryRes?.data ?? []); setDiaries(diaryData); // ... rest of the code } catch (error) { - console.error("데이터 로딩 실패:", error); + if (!cancelled) { + console.error("데이터 로딩 실패:", error); + } } }; fetchData(); + return () => { + cancelled = true; + }; }, []);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/Home.jsx` around lines 56 - 86, The first useEffect's async fetchData (calling getDiariesList, getDiaryRecommendation, getUserSummary) lacks an unmount cancellation guard; add a local cancelled flag (let cancelled = false) in the useEffect, check if (!cancelled) before calling state setters (setDiaries, setTotalDays, setRecentPhotos, setRecommendation, setSummary) after each awaited response, and return a cleanup function that sets cancelled = true so no state updates occur after the component unmounts.src/pages/EditDiary.jsx (1)
104-108: 날짜가 빈 문자열일 경우 파싱 로직에서 문제가 발생할 수 있습니다.Line 33에서
data.createdAt || ""로 fallback하면 빈 문자열이 될 수 있습니다. 이 경우"".includes("-")는false를 반환하여 빈 문자열이 그대로 렌더링됩니다. 빈 날짜에 대한 처리를 명시적으로 추가하는 것이 좋습니다.💡 빈 날짜 처리 개선
<h2> - {date.includes("-") + {date && date.includes("-") ? `${date.split("-")[0]}년 ${parseInt(date.split("-")[1])}월 ${parseInt(date.split("-")[2])}일` - : date} + : date || "날짜 없음"} </h2>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/pages/EditDiary.jsx` around lines 104 - 108, The displayed date rendering currently assumes `date` may be non-empty and uses `date.includes("-")` which leaves an empty string rendered when `date` is falsy; update the rendering logic (the `date` variable coming from `data.createdAt || ""` and the <h2> block) to explicitly check for an empty/falsy `date` before parsing and render a safe placeholder (e.g., "날짜 없음" or "—") when missing; when present, keep the existing hyphen-split parsing (use `date.split("-")` / `parseInt` as before) so the component never attempts to parse or display an empty string.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/pages/Home.jsx`:
- Around line 78-79: getUserSummary() 응답이 없을 때 summaryRes.data 접근으로 런타임 에러가 발생할
수 있습니다; 수정하려면 Home.jsx의 호출부에서 summaryRes가 falsy인지 확인하거나 optional
chaining/default 값을 사용하여 안전하게 처리하세요 (참조: getUserSummary, summaryRes,
setSummary). 예: 검사 후 setSummary(summaryRes?.data ?? /* 빈 상태 또는 기본값 */) 또는 에러/빈
응답일 때 별도 분기 처리하여 setSummary를 호출하도록 변경하세요.
---
Outside diff comments:
In `@src/pages/EditDiary.jsx`:
- Around line 88-94: Category icons (CategoryImg) show a pointer cursor but lack
click handlers; either remove the cursor from the CategoryImg styled-component
or make them interactive by adding state and onClick handlers: in EditDiary add
a piece of state like selectedEmotion and a handler function
handleSelectEmotion(emotion) that calls setSelectedEmotion, pass onClick={() =>
handleSelectEmotion('happy'|'sad'|...)} to each CategoryImg instance, and update
CategoryImg styling to accept a selected prop (e.g., props.selected) to render a
visible selected style and keep cursor: pointer only when an onClick/clickable
prop is present.
---
Nitpick comments:
In `@src/pages/EditDiary.jsx`:
- Around line 104-108: The displayed date rendering currently assumes `date` may
be non-empty and uses `date.includes("-")` which leaves an empty string rendered
when `date` is falsy; update the rendering logic (the `date` variable coming
from `data.createdAt || ""` and the <h2> block) to explicitly check for an
empty/falsy `date` before parsing and render a safe placeholder (e.g., "날짜 없음"
or "—") when missing; when present, keep the existing hyphen-split parsing (use
`date.split("-")` / `parseInt` as before) so the component never attempts to
parse or display an empty string.
In `@src/pages/Home.jsx`:
- Around line 257-269: The list is using the loop index as the React key which
can cause incorrect rendering when items reorder; update the mapping in the
RecentPhotosList to use a stable unique identifier (e.g., photo.diaryId) as the
key instead of index — locate the map over recentPhotos (where
RecentImageWrapper, RecentImage and handlePhotoClick are used) and change key
from index to the unique id (or a stable fallback property if diaryId may be
absent).
- Around line 170-171: The date parsing for recommendation.targetDate is
brittle: validate that recommendation.targetDate is a string matching the
expected YYYY-MM-DD pattern before calling split and parseInt, e.g., check
typeof recommendation.targetDate === 'string' and a simple regex like
/^\d{4}-\d{1,2}-\d{1,2}$/; if validation fails, use a safe fallback (e.g., empty
string, null, or a localized "Invalid date" label) for formattedDate and avoid
calling dateParts[?] or parseInt, and ensure dateParts length is checked
(dateParts.length === 3) before constructing formattedDate to prevent runtime
errors in the code that defines dateParts and formattedDate.
- Around line 56-86: The first useEffect's async fetchData (calling
getDiariesList, getDiaryRecommendation, getUserSummary) lacks an unmount
cancellation guard; add a local cancelled flag (let cancelled = false) in the
useEffect, check if (!cancelled) before calling state setters (setDiaries,
setTotalDays, setRecentPhotos, setRecommendation, setSummary) after each awaited
response, and return a cleanup function that sets cancelled = true so no state
updates occur after the component unmounts.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: fa73db24-a6b5-4d73-9ea1-c7065296406e
📒 Files selected for processing (5)
src/apis/photo.api.jssrc/pages/Diary.jsxsrc/pages/EditDiary.jsxsrc/pages/Home.jsxsrc/pages/PhotoBook.jsx
🚧 Files skipped from review as they are similar to previous changes (3)
- src/apis/photo.api.js
- src/pages/PhotoBook.jsx
- src/pages/Diary.jsx
📜 Review details
🔇 Additional comments (7)
src/pages/Home.jsx (3)
111-134: 감정 분포 그래프 스타일 계산 로직이 잘 구현되었습니다.방어적 코딩으로
summary및emotionDistribution검증을 수행하고, 빈 데이터에 대한 fallback 처리가 적절합니다.
136-158:tileContent로직이 개선되었습니다.이전 리뷰 코멘트에서 지적된 날짜 필드 불일치 문제가 해결되었습니다. 현재
tileContent는calendarDataAPI 응답을 사용하고,onClickDay는diariesAPI 응답을 사용하여 각 데이터 소스에 맞는 적절한 필드를 참조하고 있습니다.
280-320: 추천 일기 조건부 렌더링이 잘 구현되었습니다.
recommendation.diaryId유무에 따라 추천 버블과 기본 환영 메시지를 적절히 분기 처리하고 있습니다.$clickabletransient prop을 사용하여 styled-components에서 DOM 경고를 방지한 점도 좋습니다.src/pages/EditDiary.jsx (4)
26-49: 데이터 페칭 로직이 잘 구현되었습니다.
isLoading상태 관리, 에러 처리,finally블록을 통한 로딩 상태 해제가 적절합니다.
63-75: 이전 리뷰에서 지적된alert()문제가 해결되었습니다.에러 객체를
console.error로 출력하고, 사용자에게는 읽기 쉬운 메시지를 보여주는 패턴이 적절합니다.
19-22: 초기imageUrls상태가 테스트 이미지를 포함하고 있습니다.API 응답에 이미지가 없을 경우(
data.imageUrls가 빈 배열) 테스트 이미지가 표시되지 않지만, API 호출이 실패하거나imageUrls필드가 없을 경우Test이미지가 그대로 유지됩니다. 의도된 동작인지 확인이 필요합니다.
125-152: 이미지 캐러셀 컨트롤이 잘 구현되었습니다.이미지가 여러 개일 때만 prev/next 버튼을 표시하고,
type="button"과aria-label을 사용하여 접근성을 고려한 점이 좋습니다.
fix: 토큰이 노출 삭제
Feat/api login
No description provided.